const { defineConfig } = require('@vue/cli-service');
const TerserPlugin = require('terser-webpack-plugin');
const timeTemps = new Date().getTime();
// var obfuscator = require('webpack-obfuscator');

module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  assetsDir: 'static',
  productionSourceMap: false,
  devServer: {
    client: {
      overlay: {
        runtimeErrors: false
      }
    }
  },
  configureWebpack: (config) => {
    // config.externals = {
    //   vue: 'Vue',
    //   'view-design': 'iview',
    //   iview: 'ViewUI'
    // }

    config.optimization.splitChunks = {
      chunks: 'async', // 只处理异步 chunk，这里两个缓存组都另配了 chunks，那么就被无视了 
      minSize: 30000, // 允许新拆出 chunk 的最小体积
      maxSize: 300000, // 旨在与 HTTP/2 和长期缓存一起使用。它增加了请求数量以实现更好的缓存。它还可以用于减小文件大小，以加快二次构建速度。
      minChunks: 1, // 拆分前被 chunk 公用的最小次数
      maxAsyncRequests: 5, // 每个异步加载模块最多能被拆分的数量
      maxInitialRequests: 3, // 每个入口和它的同步依赖最多能被拆分的数量
      automaticNameDelimiter: '~',
      cacheGroups: { // 缓存组
        vendors: {
          name: `chunk-vendors`,
          test: /[\\/]node_modules[\\/]/,
          priority: -10, // 缓存组权重，数字越大优先级越高
          chunks: 'initial' // 只处理初始 chunk
        },
        common: {
          name: `chunk-common`,
          minChunks: 2, // common 组的模块必须至少被 2 个 chunk 共用 (本次分割前) 
          priority: -20,
          chunks: 'initial', // 只针对同步 chunk
          reuseExistingChunk: true  // 复用已被拆出的依赖模块，而不是继续包含在该组一起生成
        }
      },
    };
    config.optimization.minimizer.push(
      new TerserPlugin({
        extractComments: false,
        terserOptions: { compress: { drop_console: true } },
      })
    );
    config.module.rules.push({
      test: /\.worker.js$/,
      use: {
        loader: 'worker-loader',
        // 允许将内联的 web worker 作为 BLOB
        options: { inline: 'no-fallback' }
      }
    });
    // 添加webpack-obfuscator插件实例，用于混淆代码
    // config.plugins.push(
    //   new obfuscator({
    //     exclude: ['@/api/user.js', '@/api/activity.js', '@/api/address.js', '@/api/administrativedivisions.js', '@/api/base.js', '@/api/card.js', '@/api/cart.js', '@/api/chatLog.js', '@/api/content.js', '@/api/expressOrder.js', '@/api/favorites.js', '@/api/invite.js', '@/api/lang.js', '@/api/logistics.js', '@/api/order.js', '@/api/product.js', '@/api/sys.js', '@/api/user.js', '@/api/withdraw.js', 'src/router/index.js', 'node_modules/**'],
    //     // 压缩,无换行
    //     compact: true,
    //     // 是否启用控制流扁平化(降低1.5倍的运行速度)
    //     controlFlowFlattening: false,
    //     // 应用概率;在较大的代码库中，建议降低此值，因为大量的控制流转换可能会增加代码的大小并降低代码的速度。
    //     controlFlowFlatteningThreshold: 0.75,
    //     // 随机的死代码块(增加了混淆代码的大小)
    //     deadCodeInjection: false,
    //     // 死代码块的影响概率
    //     deadCodeInjectionThreshold: 0.4,
    //     // 此选项几乎不可能使用开发者工具的控制台选项卡
    //     debugProtection: false,
    //     // 如果选中，则会在“控制台”选项卡上使用间隔强制调试模式，从而更难使用“开发人员工具”的其他功能。
    //     debugProtectionInterval: 1,
    //     // 通过用空函数替换它们来禁用console.log，console.info，console.error和console.warn。这使得调试器的使用更加困难。
    //     disableConsoleOutput: false,
    //     //锁定混淆的源代码，使其仅在特定域和/或子域上运行。这使得某人只需复制并粘贴您的源代码并在其他地方运行就变得非常困难。
    //     domainLock: [],
    //     //标识符的混淆方式 hexadecimal(十六进制) mangled(短标识符)
    //     identifierNamesGenerator: 'hexadecimal',
    //     //全局标识符添加特定前缀,在混淆同一页面上加载的多个文件时使用此选项。此选项有助于避免这些文件的全局标识符之间发生冲突。为每个文件使用不同的前缀
    //     identifiersPrefix: '',
    //     inputFileName: '',
    //     // 允许将信息记录到控制台。
    //     log: false,
    //     // 是否启用全局变量和函数名称的混淆
    //     renameGlobals: false,
    //     // 禁用模糊处理和生成标识符
    //     reservedNames: [],
    //     // 禁用字符串文字的转换
    //     reservedStrings: [],
    //     // 通过固定和随机（在代码混淆时生成）的位置移动数组。这使得将删除的字符串的顺序与其原始位置相匹配变得更加困难。如果原始源代码不小，建议使用此选项，因为辅助函数可以引起注意。
    //     rotateStringArray: true,
    //     // 混淆后的代码,不能使用代码美化,同时需要配置 cpmpat:true;
    //     seed: 0,
    //     selfDefending: false,
    //     sourceMap: false,
    //     sourceMapBaseUrl: '',
    //     sourceMapFileName: '',
    //     sourceMapMode: 'separate',
    //     // 删除字符串文字并将它们放在一个特殊的数组中
    //     stringArray: true,
    //     // 编码的所有字符串文字stringArray使用base64或rc4并插入即用其解码回在运行时的特殊代码。true（boolean）：stringArray使用编码值base64;false（boolean）：不编码stringArray值;'base64'（string）：stringArray使用编码值base64;'rc4'（string）：stringArray使用编码值rc4。大约慢30-50％base64，但更难获得初始值。建议禁用unicodeEscapeSequence带rc4编码的选项以防止非常大的混淆代码。
    //     stringArrayEncoding: ['none'],
    //     // 调整字符串文字将插入stringArray的概率
    //     stringArrayThreshold: 0.75,
    //     // 您可以将混淆代码的目标环境设置为以下之一：Browser;Browser No Eval;Node
    //     target: 'browser',
    //     // 是否启用混淆对象键
    //     transformObjectKeys: false,
    //     // 允许启用/禁用字符串转换为unicode转义序列。Unicode转义序列大大增加了代码大小，并且可以轻松地将字符串恢复为原始视图。建议仅对小型源代码启用此选项。
    //     unicodeEscapeSequence: false
    //   }, [])
    // );
  },
  chainWebpack: config => {
    // config.module
    //     .rule("vue")
    //     .use("iview-loader") // 解决ivew组件 忽略前缀i的问题
    //     .loader("iview-loader")
    //     .options({
    //       prefix: false,
    //     })
    //     .end();
    // config.plugin('html').tap(args => {
    //   args[0].title = 'CoinAB';
    //   return args;
    // });

    config.output.filename(`static/js/[chunkhash:8].[name].${timeTemps}.js`).end();
    config.output.chunkFilename(`static/js/[chunkhash:8].[name].${timeTemps}.js`).end();
  },
  css: { // 配置css模块
    extract: true,
    loaderOptions: { // 向预处理器 Loader 传递配置选项
      less: { // 配置less（其他样式解析用法一致）
        javascriptEnabled: true // 设置为true
      }
    }
  },
  pluginOptions: {
    'style-resources-loader': {
      preProcessor: 'less',
      patterns: [
        './src/assets/less/theme/theme.less'
      ]
    },
    i18n: {
      locale: 'en',
      fallbackLocale: 'en',
      localeDir: 'locales',
      enableInSFC: false,
      enableBridge: false
    }
  }
});
